package generic.interface1;

import java.util.Iterator;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class Fibonacci implements Supplier<Integer> {
    private int count = 0;
    @Override
    public Integer get() {
        return fib(count++);
    }

    public int fib(int n) {
        if(n < 2) return 1;
        return fib(n-2) + fib(n-1);
    }

    public static void main(String[] args) {
        Stream.generate(new Fibonacci())
                .limit(18)
                .map(n-> n + " ")
                .forEach(System.out::println);
    }
}

class IterableFibonacci extends Fibonacci implements Iterable<Integer> {

    private  int n;

    public IterableFibonacci(int count) {
        n = count;
    };

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            @Override
            public boolean hasNext() {
                return n > 0;
            }

            @Override
            public Integer next() {
                n--;
                return IterableFibonacci.this.get();
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public static void main(String[] args) {
        for(int i: new IterableFibonacci(18)) {
            System.out.println(i + " ");
        }
    }
}
